package ui;

import java.awt.Point;
import java.awt.Toolkit;
import java.util.ArrayList;

import board.Board;
import board.NodeLabel;
import board.NodeMark;
import board.SimpleMark;

import ui.tools.EditTool;

/**
 * Controller that manages interactions with static diagrams.
 * @author TKington
 *
 */
public class EditController implements IGobanListener {
	/** The one and only instance. */
	private static EditController instance;
	
	/** The currently selected EditTool. */
	private EditTool curTool;
	/** The GobanPanel being edited. */
	private GobanPanel goban;
	/** The Board being edited. */
	private Board board;
	
	/** Creates the single instance. */
	private EditController() { /* */ }
	
	/**
	 * Returns the EditController instance.
	 * @return the EditController instance
	 */
	public static EditController instance() {
		if(instance == null)
			instance = new EditController();
		return instance;
	}
	
	/**
	 * Sets the Board this EditController will operate on.
	 * @param b the Board
	 */
	public void setBoard(Board b) { board = b; }
	
	/**
	 * Sets the GobanPanel that is displaying the Board.
	 * @param g the GobanPanel
	 */
	public void setGoban(GobanPanel g) { goban = g; }
	
	/**
	 * Sets the currently active EditTool.
	 * @param tool the EditTool
	 */
	public void setEditTool(EditTool tool) {
		curTool = tool;
	}

	public void mouseClicked(int x, int y, int modifiers) {
		if(curTool.mouseClicked(x, y, modifiers)) {
    		Main.frame.setDirty(true);
    		goban.repaint(x, y);
		}
    	else Toolkit.getDefaultToolkit().beep();
	}

	/**
	 * Removes a SimpleMark from the Board.
	 * @param m the SimpleMark
	 */
	public void removeMark(SimpleMark m) {
		board.removeMark(m);
	}

	/**
	 * Gets the first SimpleMark on the Board at [x,y]
	 * @param x the x location
	 * @param y the y location
	 * @return the SimpleMark
	 */
	public SimpleMark getSimpleMark(int x, int y) {
		ArrayList<NodeMark> mks = board.getMarks();
		for(NodeMark mk : mks) {
			if (mk instanceof SimpleMark) {
				SimpleMark sm = (SimpleMark) mk;
				Point p = sm.getPoint();
				if(p.x == x && p.y == y)
					return sm;
			}
		}
		return null;
	}

	/**
	 * Adds a NodeMark to the Board.
	 * @param mark the NodeMark
	 */
	public void addMark(NodeMark mark) {
		board.addMark(mark);
	}

	/**
	 * Finds the first unused alphabetic label.
	 * @return the first unused label
	 */
	public String getNextLabel() {
		ArrayList<NodeMark> marks = board.getMarks();
		
    	for(int j = -1; j < 26; j++) {
    		String prefix = ""; //$NON-NLS-1$
    		if(j != -1) {
    			char c = (char)('A' + j);
    			prefix += c;
    		}
    		
	    	for(int i = 0; i < 26; i++) {
	    		char c = (char)('A' + i);
	    		String l = prefix + c;
	    		
	    		boolean found = false;
	    		for(NodeMark mark : marks) {
					if(mark instanceof NodeLabel) {
						NodeLabel label = (NodeLabel)mark;
						if(l.equals(label.getText())) {
							found = true;
							break;
						}
					}
				}
	    		
	    		if(!found)
	    			return l;
	    	}
    	}
    	
    	return "You must be joking"; //$NON-NLS-1$
	}

	/**
	 * Finds the first unused numeric label.
	 * @return the numeric label
	 */
	public String getNextNumberLabel() {
		ArrayList<NodeMark> marks = board.getMarks();
		
    	for(int i = 1; i < 500; i++) {
    		String l = String.valueOf(i);
    		
    		boolean found = false;
    		for(NodeMark mark : marks) {
				if(mark instanceof NodeLabel) {
					NodeLabel label = (NodeLabel)mark;
					if(l.equals(label.getText())) {
						found = true;
						break;
					}
				}
			}
    		
    		if(!found)
    			return l;
    	}
    	
    	return null;
	}

	/**
	 * Gets the stone present on the Board at x,y
	 * @param x the x location
	 * @param y the y location
	 * @return -1 for white, 0 for empty, 1 for black
	 */
	public int getAt(int x, int y) {
		return board.getAt(x, y);
	}

	/**
	 * Sets the stone on the Board at x,y
	 * @param x the x location
	 * @param y the y location
	 * @param color 1 for black, -1 for white
	 */
	public void setAt(int x, int y, int color) {
		board.setAt(x, y, color);
	}

	public void mouseWheelMoved(int wheelRotation) {
		//	No mousewheel support right now
	}
}
